package com.scalar.chiptrack.adaptor.ikanos.silterra;

import com.scalar.chiptrack.jobs.JobHandler;
import com.scalar.chiptrack.adaptor.AdaptorConstants;
import com.scalar.chiptrack.adaptor.AdaptorUtils;
import com.scalar.chiptrack.adaptor.dao.AdaptorRunInfo;
import com.scalar.chiptrack.users.VendorAdaptor;
import com.scalar.chiptrack.users.dao.AdaptorSetUpDAO;
import com.scalar.chiptrack.utils.Logger;
import com.scalar.chiptrack.utils.StringUtils;
import com.scalar.chiptrack.utils.DateUtil;
import com.scalar.ScalarException;

import HTTPClient.HTTPConnection;
import HTTPClient.HTTPResponse;
import HTTPClient.CookieModule;
import HTTPClient.NVPair;
import HTTPClient.Cookie;

import java.io.BufferedInputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.net.URL;
import java.util.Calendar;

import Acme.HtmlScanner;

/**
 * Created by IntelliJ IDEA.
 * User: Sudhakar
 * Date: Aug 30, 2006
 * Time: 12:08:56 AM
 */
public class SilterraAdaptor extends JobHandler implements AdaptorConstants
{
    private static final String PROTOCOL_SCHEME_HTTPS   = "https";
    private static final String HOST                    = "myfab.silterra.com";
    private static final String POST_URI_LOGIN          = "/MyFab/appmanager/MyFab/Login;jsessionid=";
    private static final String WIP_REPORT_QUERY        = "/MyFab/appmanager/MyFab/Ikanos?_nfpb=true&_pageLabel=MyFab_WIPReport";
    private static final String GET_WIP_REPORT          = "/MyFab/appmanager/MyFab/Ikanos?_nfpb=true&portlet_6_4_actionOverride=%2Fportlets%2FWIPReport%2Fbegin&_windowLabel=portlet_6_4&_pageLabel=MyFab_WIPReport";
    private static final String POST_URI_SHIP_REPORT    = "/MyFab/appmanager/MyFab/Ikanos?_nfpb=true&_pageLabel=MyFab_ShipmentReport";
    private static final String GET_SHIP_REPORT         = "/MyFab/appmanager/MyFab/Ikanos?_nfpb=true&portlet_2_5_actionOverride=%2Fportlets%2FshipmentReport%2FshipmentReport&_windowLabel=portlet_2_5&_pageLabel=MyFab_ShipmentReport";
    private static final String GET_URI_LOGOUT          = "/MyFab/portlets/Login/logout.jsp";
    public static final String FILE_NAME_WIP_STATUS     = "SILTTERA_WIP_STATUS";
    public static final String FILE_NAME_SHIP_STATUS    = "SILTTERA_SHIP_STATUS";

    private static URL s_dummyUrl                   = null;
    private static final int DEFAULT_SSL_PORT       = 443;
    private static final int RESPONSE_CODE_ERROR    = 400;
    private SilterraHtmlObserver m_observer         = null;
    public static final String ADAPTOR_NAME         = "SILTERRA_FAB";

    private String m_dataOutputDir      = null;
    private Logger m_adaptorLogger      = null;
    private String m_username           = null;
    private String m_password           = null;
    private int    m_adaptor_id         = -1;

    public SilterraAdaptor() throws Exception
    {
        if (s_dummyUrl == null)
        {
            try
            {
                s_dummyUrl = new URL("https://" + HOST + "/");
            }
            catch (Exception ignore)
            {
                throw ignore;
            }
        }
        try
        {
            VendorAdaptor vendorAdaptor = AdaptorSetUpDAO.getVendorAdaptorDetailsByVendorNameAndLocation(VENDOR_NAME_SILTERRA, LOCATION_TYPE_FAB);

            if (vendorAdaptor == null)
            {
                log("ERROR!! ERROR!! ERROR!! Exception while loading SILTERRA Adaptor Username, Password details from database");
                throw new ScalarException("Exception while loading SILTERRA Adaptor Username, Password details from database");
            }

            m_username      = vendorAdaptor.getUserId().trim();
            m_password      = vendorAdaptor.getPassWord().trim();
            m_dataOutputDir = vendorAdaptor.getOutPutDirectory().trim();

            if (m_dataOutputDir != null)
            {
                if (m_dataOutputDir.endsWith("/") || m_dataOutputDir.endsWith("\\"))
                {
                    m_dataOutputDir = m_dataOutputDir + m_username;
                }
                else
                {
                    m_dataOutputDir = m_dataOutputDir + "/" + m_username;
                }

                AdaptorUtils.makeAllAdaptorDirs( m_dataOutputDir );
                m_adaptorLogger = AdaptorUtils.getAdaptorLogger( m_dataOutputDir,VENDOR_NAME_SILTERRA );
                AdaptorUtils.setLogger( m_adaptorLogger );
            }
        }
        catch (Exception se)
        {
            log("ERROR!! ERROR!! ERROR!! Exception while loading SILTERRA Adaptor Username, Password details from database, Exception: " + se);
            throw new ScalarException("Exception while loading SILTERRA Adaptor Username, Password details from database");
        }
        m_observer = new SilterraHtmlObserver();
    }

    public static void main(String[] args) throws Exception
    {
        new SilterraAdaptor().execute();
    }

    /**
     * @throws Exception
     */
    public void execute() throws Exception
    {
        try
        {
            m_adaptor_id = AdaptorRunInfo.saveAdaptorLastUpdatedStatus( CONSTANT_ADAPTOR, ADAPTOR_NAME, CONSTANT_SUCCESS, -1);

            // Step 1
            // prints the version of Adaptor
            AdaptorUtils.printHeader(VENDOR_NAME_SILTERRA, CONSTANT_ADAPTOR );

            // Step 2
            // removes the old files out side done directory
           AdaptorUtils.removeOldFiles(m_dataOutputDir, m_adaptorLogger);

            //login into Silterra Site
            HTTPConnection connection = login(HOST, DEFAULT_SSL_PORT, m_username, m_password);

           if (connection != null)
            {
                //Downloding Wip Report
                BufferedInputStream bfReader = null;
                BufferedReader reader = null;

                HTTPResponse rsp = requestWipReport(connection);

                if (rsp != null)
                {
                    bfReader = new BufferedInputStream(rsp.getInputStream());
                    if (bfReader != null)
                    {
                        System.out.print("\tDownloading and Saving Wip Report.... ");
                        log("\n Downloading  and Saving Wip Report.... ");
                        AdaptorUtils.saveAsBinaryFile(bfReader, m_dataOutputDir, FILE_NAME_WIP_STATUS, FILE_EXTN_CSV, true);

                        if ( m_adaptor_id > 0 )
                        {
                            AdaptorRunInfo.saveAdaptorFileInfo( m_adaptor_id , FILE_NAME_WIP_STATUS, FILE_EXTN_CSV, StringUtils.formatDateandTime(DateUtil.getFormattedTimeStamp() )) ;
                        }
                        System.out.println("\nDone  " );
                    }
                    else
                    {
                        log("Could not save WIP Status Sheet from Buffer Reader");
                        throw new ScalarException("Could not save WIP Status Sheet from Buffer Reader");
                    }
                }
                else
                {
                    log("Could not create response object of WIP Status Sheet");
                    throw new ScalarException("Could not create response object of WIP Status Sheet");
                }
                //Downloding the Ship information
                rsp = requestShipInfo(connection);

                if (rsp != null)
                {
                    reader = new BufferedReader(new InputStreamReader(rsp.getInputStream()));
                    if (reader != null)
                    {
                        System.out.print("\tDownloading and Saving Shipment Report.... ");
                        log("\n Downloading  and Saving Shipment Report.... ");
                        
                        AdaptorUtils.saveAsFile(reader, m_dataOutputDir, FILE_NAME_SHIP_STATUS, FILE_EXTN_HTML);

                        if ( m_adaptor_id > 0 )
                        {
                            AdaptorRunInfo.saveAdaptorFileInfo( m_adaptor_id , FILE_NAME_SHIP_STATUS, FILE_EXTN_HTML, StringUtils.formatDateandTime(DateUtil.getFormattedTimeStamp() )) ;
                        }
                        System.out.println("\nDone  " );
                    }
                    else
                    {
                        log("Could not save SHIP Status Sheet from Buffer Reader");
                        throw new ScalarException("Could not save SHIP Status Sheet from Buffer Reader");
                    }
                }
                else
                {
                    log("Could not create response object of SHIP Status Sheet");
                    throw new ScalarException("Could not create response object of SHIP Status Sheet");
                }
                //log out the silterra site
                logout(connection);

                bfReader = null;
                reader   = null;
            }
            else
            {
                log("Could not able to get the Connection to web site");
                throw new ScalarException("Could not able to get the Connection to web site");
            }
        }
        catch(Exception e )
        {
            AdaptorUtils.removeOldFiles( m_dataOutputDir, m_adaptorLogger);
            AdaptorRunInfo.updatedAdaptorStatus( CONSTANT_FAILURE, m_adaptor_id );
            System.out.println("Exception while trying to connect and read data from "+HOST +" site: " + e);
            e.printStackTrace();
            throw e;
        }
    }

    /**
     * @param host
     * @param port
     * @param username
     * @param password
     * @return
     * @throws Exception
     */
    private HTTPConnection login(String host, int port, String username, String password) throws Exception
    {
        String sessionId    = null;
        byte[] data         = new byte[1024];

        HTTPConnection conn = new HTTPConnection(PROTOCOL_SCHEME_HTTPS, host, port);
        CookieModule.setCookiePolicyHandler(null);
        HTTPConnection.addDefaultModule(CookieModule.class, -1);

        NVPair defaultHeaders[] = new NVPair[ 9 ];
        defaultHeaders[0] = new NVPair("Accept", "*/*");
        defaultHeaders[1] = new NVPair("Referer", "http://" + host);
        defaultHeaders[2] = new NVPair("Accept-Language", "en-us");
        defaultHeaders[3] = new NVPair("Content-Type", "application/x-www-form-urlencoded");
        defaultHeaders[4] = new NVPair("Proxy-Connection", "Keep-Alive");
        defaultHeaders[5] = new NVPair("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)");
        defaultHeaders[6] = new NVPair("Host", host);
        defaultHeaders[8] = new NVPair("Pragma", "no-cache");

        conn.setDefaultHeaders(defaultHeaders);
        HTTPResponse rsp = conn.Get("/");

        while (rsp.getInputStream().read(data) != -1) {
            //log(new String(data));
        }

        Cookie[] cookie = CookieModule.listAllCookies();

        for ( int i = 0; i < cookie.length; i++ )
        {
            //System.out.println("i="+i+" Name = "+cookie[i].getName()+" Value = "+cookie[i].getValue());
            if ( cookie[i].getName() != null && cookie[i].getName().trim().equalsIgnoreCase( "jsessionid" ) )
            {
                sessionId = cookie[i].getValue();
            }
        }

        NVPair[] formData = new NVPair[ 4 ];

        formData[0] = new NVPair("username", username);
        formData[1] = new NVPair("password", password);
        formData[2] = new NVPair("yahoo_login", "true");
        formData[3] = new NVPair("Submit", "Enter");

        System.out.print("Trying to Logging in......");
        log("Trying to Logging in......");

        rsp = conn.Post(POST_URI_LOGIN + sessionId + "?_nfpb=true&_windowLabel=portlet_MyFab_SignIn_1&_cuid=RC_t_4023&_event=redirect&_pageLabel=MyFab_page_31", formData);
                
        if (rsp.getStatusCode() >= RESPONSE_CODE_ERROR)
        {
            System.out.println("Login failed.. response from server: " + rsp.getStatusCode());
            log("Login failed.. response from server: " + rsp.getStatusCode());
            conn = null;
        }

        while (rsp.getInputStream().read(data) != -1) {
            //System.out.println(new String(data));
        }
        System.out.println("Done.");
        log("Done.");
        return conn;
    }

    /**
     * @param conn
     * @return
     * @throws Exception
     */
    private HTTPResponse requestWipReport(HTTPConnection conn) throws Exception
    {
        byte[] data         = new byte[1024];
        HTTPResponse rsp    = null;

        System.out.println("\tPassing through the Wip Report .... ");
        log("\nPassing through the Wip Report ..... ");

        try
        {
            rsp = conn.Get( WIP_REPORT_QUERY );

            System.out.println("\tSubmitting HTTP Request for Wip Report .... ");
            log("\nSubmitting HTTP Request for Wip Report ..... ");

            NVPair[] formData = new NVPair[ 3 ];

            formData[0] = new NVPair("portlet_6_4actionOverride:searchWIPReport", "   Search   ");
            formData[1] = new NVPair("portlet_6_4actionOverride:selectLot", "Show LotWatch lots");
            formData[2] = new NVPair("portlet_6_4actionOverride:customize", "Customize");

            rsp = conn.Post(GET_WIP_REPORT, formData);

            HtmlScanner htmlScanner = new HtmlScanner(rsp.getInputStream(), s_dummyUrl, m_observer);

            while (htmlScanner.read(data) != -1)
            {
            }
                            
            rsp = conn.Get(m_observer.getDownloadURL());

        }
        catch (Exception e)
        {
            log("Could not send request for the Wip Report Sheet, Exception : " + e);
            e.printStackTrace();
            throw new ScalarException("Could not send request for the Wip Report Sheet");
        }
        return rsp;
    }

    /**
     * To get the shipping information
     * @param conn
     * @throws Exception
     */
    private HTTPResponse requestShipInfo(HTTPConnection conn) throws Exception
    {
        BufferedReader reader = null;

        System.out.println("\tPassing through the Shipping Info Status .... ");
        log("\nPassing through the Shipping Info Status ..... ");
        byte[] data = new byte[1024];
        HTTPResponse rsp = null;

        try
        {
            rsp = conn.Get(POST_URI_SHIP_REPORT);
            while (rsp.getInputStream().read(data) != -1)
            {
                //log(new String(data));
            }

            Calendar calendar = Calendar.getInstance();
            String shippingInfoEndDate = StringUtils.formatDateToString(calendar.getTime(), "dd-MMM-yyyy");
            calendar.add(Calendar.DATE, -15);
            String shippingInfoStartDate = StringUtils.formatDateToString(calendar.getTime(), "dd-MMM-yyyy");

            System.out.println("\tSubmitting HTTP Request for Shipping Info Status .... ");
            log("\n Submitting HTTP Request for Shipping Info Status ..... ");

            NVPair[] formData = new NVPair[ 4 ];

            formData[0] = new NVPair("portlet_2_5{actionForm.fromdate}", shippingInfoStartDate);
            formData[1] = new NVPair("portlet_2_5{actionForm.todate}", shippingInfoEndDate);
            formData[2] = new NVPair("portlet_2_5{pageContext.Cust_No}", "");
            formData[3] = new NVPair("submit", "View Report");

            rsp = conn.Post(GET_SHIP_REPORT, formData);
        }
        catch (Exception e)
        {
            log("Could not send request for the SHIP Status Sheet, Exception : " + e);
            e.printStackTrace();
            throw new ScalarException("Could not send request for the SHIP Status Sheet");
        }
        return rsp;
    }

    /** log out the from site
     * @param connection
     */
    public void logout(HTTPConnection connection)
    {
        try
        {
            connection.Get(GET_URI_LOGOUT);
            System.out.println("\tSuccessfully logged out from Silterra Site");
            log("Successfully logged out from Silterra Site");
            connection = null;
        }
        catch (Exception e)
        {
        }
    }
        
    /**
     *
     * @param message
     */
    private void log(String message)
    {
        if (message == null) return;

        if (m_adaptorLogger != null)
        {
            synchronized (m_adaptorLogger)
            {
                m_adaptorLogger.logDebug(message + LINE_SEPARATOR);
            }
        }
        else
        {
            System.out.println(message);
        }
    }
}
